package com.js.admin.service;

import com.js.admin.constant.AdminConstant;
import com.js.admin.entity.BaseElement;
import com.js.admin.entity.BaseMenu;
import com.js.admin.entity.BaseUser;
import com.js.admin.model.FrontUser;
import com.js.api.model.PermissionInfo;
import com.js.api.model.UserInfo;
import com.js.core.context.BaseContextHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author ygl
 * @create 2018-10-30
 * @DESCRIPTION
 * 提供权限相关服务
 **/
@Service
public class PermissionService{

    @Autowired
    private BaseMenuService baseMenuService;

    @Autowired
    private BaseElementService baseElementService;

    @Autowired
    private BaseUserService baseUserService;

    //TODO 缓存
    public List<PermissionInfo> getPermissionByUserId(String userId,String clientId) {
        // 查询用户拥有的菜单权限
        List<BaseMenu> menus = baseMenuService.getUserAuthorityMenuByUserId(userId, clientId);
        List<PermissionInfo> result = new ArrayList<PermissionInfo>();
        menu2permission(menus, result);
        // 查询用户拥有的资源权限
        List<BaseElement> elements = baseElementService.getAuthorityElementByUserId(BaseContextHandler.getUserId());
        element2permission(elements,result);
        return result;
    }

    /**
     * 获取前台需要的用户信息
     * @return
     * @throws Exception
     */
    public FrontUser getUserInfo() throws Exception {
        String userId = BaseContextHandler.getUserId();
        if (userId == null) {
            return null;
        }

        UserInfo user = this.getUserByUserId(userId);
        FrontUser frontUser = new FrontUser();
        BeanUtils.copyProperties(user, frontUser);
        // 用户所有的权限
        List<PermissionInfo> permissionInfos = this.getPermissionByUserId(userId,BaseContextHandler.getClientId());
        // 用户菜单权限
        Stream<PermissionInfo> menus = permissionInfos.parallelStream().filter((permission) -> {
            return permission.getType().equals(AdminConstant.RESOURCE_TYPE_MENU);
        });
        frontUser.setMenus(menus.collect(Collectors.toList()));
        // 用户资源权限
        Stream<PermissionInfo> elements = permissionInfos.parallelStream().filter((permission) -> {
            return !permission.getType().equals(AdminConstant.RESOURCE_TYPE_MENU);
        });
        frontUser.setElements(elements.collect(Collectors.toList()));
        return frontUser;
    }

    public UserInfo getUserByUserId(String userId) {
        UserInfo info = new UserInfo();
        BaseUser user = baseUserService.selectById(userId);
        BeanUtils.copyProperties(user, info);
        info.setId(user.getId().toString());
        return info;
    }

    /**
     * 获取所有的菜单和资源
     * @return
     */
    public List<PermissionInfo> getAllPermission() {
        List<PermissionInfo> result = new ArrayList<PermissionInfo>();
        List<BaseMenu> menus = baseMenuService.selectAll();
        menu2permission(menus, result);
        List<BaseElement> elements = baseElementService.getAllElementPermissions();
        element2permission(elements,result);
        return result;
    }

    /**
     * 菜单转成权限
     * @param menus
     * @param result
     */
    private void menu2permission(List<BaseMenu> menus, List<PermissionInfo> result) {
        PermissionInfo info;
        for (BaseMenu menu : menus) {
            if (StringUtils.isBlank(menu.getHref())) {
                menu.setHref("/" + menu.getCode());
            }
            info = new PermissionInfo();
            info.setCode(menu.getCode());
            info.setType(AdminConstant.RESOURCE_TYPE_MENU);
            info.setName(AdminConstant.RESOURCE_ACTION_VISIT);
            String uri = menu.getHref();
            if (!uri.startsWith("/")) {
                uri = "/" + uri;
            }
            info.setUri(uri);
            info.setMethod(AdminConstant.RESOURCE_REQUEST_METHOD_GET);
            result.add(info);
            info.setMenu(menu.getTitle());
        }
    }

    /**
     * 资源转成权限
     * @param elements
     * @param result
     */
    private void element2permission(List<BaseElement> elements,List<PermissionInfo> result) {
        PermissionInfo info;
        for (BaseElement element : elements) {
            info = new PermissionInfo();
            info.setCode(element.getCode());
            info.setType(element.getType());
            info.setUri(element.getUri());
            info.setMethod(element.getMethod());
            info.setName(element.getName());
            info.setMenu(element.getMenuId());
            result.add(info);
        }
    }
}
